package config

import (
	"log"
	"os"
	"sort"
	"strings"
	"sync"

	"github.com/spf13/viper"
)

const (
	// 优先级从高到低 DefaultCurrentConfigDirectory--> DefaultEnvConfigDirectory --> DefaultConfigPath

	// DefaultCurrentConfigDirectory 默认在当前运行目录中的config文件夹查找
	DefaultCurrentConfigDirectory = "config"
	// DefaultEnvConfigDirectory 环境变量-指定配置目录
	DefaultEnvConfigDirectory = "HSL_CFG_PATH"
	// DefaultConfigPath 配置文件目录
	DefaultConfigPath = "/etc/hsl"
)

var (
	once sync.Once
	//initialized atomic.Bool
)

// Initialize 初始化配置
func Initialize(path string) {
	once.Do(func() {
		var err error
		log.Printf("------------------initializing config------------------")
		// 优先从当前运行目录读取配置文件
		if path != "" {
			viper.AddConfigPath(path)
		}
		viper.AddConfigPath(DefaultCurrentConfigDirectory)
		viper.AddConfigPath(os.Getenv(DefaultEnvConfigDirectory))
		viper.AddConfigPath(DefaultConfigPath)
		viper.SetConfigType("yaml")
		viper.SetConfigName("common_config")
		viper.SetEnvPrefix("HSL")
		viper.AutomaticEnv()
		viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
		err = viper.ReadInConfig()
		if err != nil {
			log.Fatal(err)
		}
		//initialized.Store(true)
		allKeys := viper.AllKeys()
		sort.Strings(allKeys)
		for _, k := range allKeys {
			log.Printf("%s=%v\n", k, viper.Get(k))
		}
		log.Println("------------------config initialized------------------load config is", viper.ConfigFileUsed())
	})
}

// SetConfigValue 设置替换原有参数
func SetConfigValue(key string, value interface{}) {
	viper.Set(key, value)
}

// GetStringConfigValue 获取string类型的配置值
func GetStringConfigValue(key string, defaultValue string) string {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	return viper.GetString(key)
}

// GetStringConfigValues 获取string slice类型的配置值
func GetStringConfigValues(key string, defaultValue []string) []string {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	return viper.GetStringSlice(key)
}

// GetIntConfigValue 获取bool类型的配置值
func GetIntConfigValue(key string, defaultValue int) int {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	return viper.GetInt(key)
}

// GetFloat64ConfigValue 获取flaot64类型的配置值
func GetFloat64ConfigValue(key string, defaultValue float64) float64 {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	return viper.GetFloat64(key)
}

// GetBoolConfigValue 获取init类型的配置值
func GetBoolConfigValue(key string, defaultValue bool) bool {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	return viper.GetBool(key)
}

// GetPluginConfigsValue 获取插件类型的匹配值
func GetPluginConfigsValue(key string, defaultValue *PluginConfigs) *PluginConfigs {
	//checkInitialized()
	if !viper.IsSet(key) {
		return defaultValue
	}
	cfg := &PluginConfigs{}
	err := viper.UnmarshalKey(key, cfg)
	if err != nil {
		return defaultValue
	}
	return cfg
}

// GetPluginConfigsMapValue 获取插件类型的匹配值
func GetPluginConfigsMapValue(key string, defaultValue *PluginConfigs) map[string]*PluginConfig {
	plugs := GetPluginConfigsValue(key, defaultValue)
	mp := make(map[string]*PluginConfig)
	if plugs == nil {
		return mp
	}
	for _, plug := range plugs.Plugins {
		mp[plug.Name] = plug
	}
	return mp
}
